import json
import random
import time

import openpyxl

from common import errors
from lib.http import render_json
from lib.util import get_now_time
from linkutil.checkUtil import check_link_params
from linkutil.get_url import my_get_link
from user.models import User
from logs.models import Log
from link.models import Link
from project import scheduler, taskManager

# 导入日志模块
from loggings.db_logger import create_log, update_log, delete_log, query_log
from loggings.api_logger import log_api_call
from loggings.system_logger import log_error
from loggings.error_handler import exception_handler

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.validators import EmailValidator, URLValidator
from django.db.models import Q

from celery import shared_task


# 创建link数据
@log_api_call
@create_log
@exception_handler
def create_link(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        log_error(e, context={"action": "解析link创建请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
        raise errors.ParamsError("无效的JSON数据")

    # 获取当前登录用户ID
    user_id = request.session.get('user_id')
    if not user_id:
        log_error("未登录用户尝试创建链接", context={"request": str(request)})
        raise errors.AuthError("请先登录")
    
    try:
        # 获取当前用户
        current_user = User.objects.get(userId=user_id)
    except User.DoesNotExist:
        log_error(f"用户不存在: {user_id}", context={"user_id": user_id})
        raise errors.AuthError("用户不存在")
    
    # 验证数据
    # 参数校验  
    required_fields = [
        "MCCName", "UserEmail", "MCCAccount", "GoogleAccount",
        "CampaignName", "finalUrl", "OfferLink", "TargetNation", 
        "URLldentifiers", "InterVal", "Swith"
    ]

    missing_fields = [field for field in required_fields if field not in data]
    if missing_fields:
        log_error(f"缺少必填字段: {missing_fields}", context={"data": data})
        raise errors.ParamsError(f"缺少必填字段: {', '.join(missing_fields)}")

    # 校验邮箱格式
    try:
        EmailValidator(message="邮箱格式无效")(data["UserEmail"])
    except Exception as e:
        log_error(e, context={"field": "UserEmail", "value": data.get("UserEmail")})
        raise errors.ParamsError(f"邮箱格式无效: {data.get('UserEmail')}")

    # 校验 URL 格式
    url_fields = ["OfferLink"]
    for url_field in url_fields:
        try:
            URLValidator(message=f"{url_field} 格式无效")(data[url_field])
        except Exception as e:
            log_error(e, context={"field": url_field, "value": data.get(url_field)})
            raise errors.ParamsError(f"{url_field} 格式无效: {data.get(url_field)}")

    if "LinkId" in data:
        # 修改link数据
        try:
            link = Link.objects.get(LinkId=data["LinkId"])
            old_link = link.to_dict()
            
            # 使用安全的方式更新字段
            try:
                link.MCCName = data["MCCName"]
                link.UserEmail = data["UserEmail"]
                link.MCCAccount = data["MCCAccount"]
                link.GoogleAccount = data["GoogleAccount"]
                link.CampaignName = data["CampaignName"]
                link.finalUrl = data["finalUrl"]
                link.OfferLink = data["OfferLink"]
                link.redirect = data["redirect"]
                link.TargetNation = data["TargetNation"]
                link.URLldentifiers = data["URLldentifiers"]
                link.InterVal = data.get("InterVal", 10)  # 可选参数，默认为 10
                link.Swith = data.get("Swith", True)  # 可选参数，默认为 True
                link.referrer = data.get("referrer", None)  # 可选参数，默认为 True
                if not link.user:
                    link.user = current_user
                link.save()
            except Exception as e:
                log_error(e, context={"action": "更新Link字段", "link_id": data["LinkId"]})
                raise errors.ParamsError(f"更新Link失败: {str(e)}")

            # 记录操作日志
            try:
                Log.create_Log(
                    userId=random.randint(1,10),
                    LogType=Log.LogTypeChoices.LINK.name,
                    LogOption=Log.LogOptionChoices.UPDATE.name,
                    LogResult=Log.LogResultChoices.SUCCESS.name,
                    LogOptionDetail=f"""修改Link数据成功，修改内容如下：
                    LinkId: {data["LinkId"]}
                    MCCName: {old_link.get("MCCName")} -> {link.MCCName}
                    UserEmail: {old_link.get("UserEmail")} -> {link.UserEmail}
                    MCCAccount: {old_link.get("MCCAccount")} -> {link.MCCAccount}
                    GoogleAccount: {old_link.get("GoogleAccount")} -> {link.GoogleAccount}
                    CampaignName: {old_link.get("CampaignName")} -> {link.CampaignName}
                    finalUrl: {old_link.get("finalUrl")} -> {link.finalUrl}
                    OfferLink: {old_link.get("OfferLink")} -> {link.OfferLink}
                    TargetNation: {old_link.get("TargetNation")} -> {link.TargetNation}
                    URLldentifiers: {old_link.get("URLldentifiers")} -> {link.URLldentifiers}
                    InterVal: {old_link.get("InterVal")} -> {link.InterVal}
                    Swith: {old_link.get("Swith")} -> {link.Swith}
                    referrer: {old_link.get("referrer")} -> {link.referrer}
                    """,
                )
                if not link.user:
                    link.user = current_user
                link.save()
            except Exception as e:
                # 记录日志失败不应该影响主流程
                log_error(e, context={"action": "记录更新Link日志", "link_id": data["LinkId"]})
                raise errors.ParamsError(f"更新Link失败: {str(e)}")
        
        except Link.DoesNotExist:
            log_error(f"Link不存在: {data['LinkId']}", context={"data": data})
            raise errors.ParamsError(f"Link不存在: {data['LinkId']}")
        except Exception as e:
            log_error(e, context={"action": "修改Link", "data": data})
            raise errors.ParamsError(f"修改Link失败: {str(e)}")
    else:
        # 创建 Link 对象
        try:
            link = Link.objects.create(
                MCCName=data["MCCName"],
                UserEmail=data["UserEmail"],
                MCCAccount=data["MCCAccount"],
                GoogleAccount=data["GoogleAccount"],
                CampaignName=data["CampaignName"],
                finalUrl=data["finalUrl"],
                OfferLink=data["OfferLink"],
                redirect=data.get("redirect", 0),  # 可选参数，默认为 0
                TargetNation=data["TargetNation"],
                URLldentifiers=data["URLldentifiers"],
                InterVal=data.get("InterVal", 10),  # 可选参数，默认为 10
                Swith=data.get("Swith", True),  # 可选参数，默认为 True
                referrer=data.get("referrer", None)  # 可选参数，默认为 True
            )
            link.user = current_user
            link.save()

            # 记录操作日志
            try:
                Log.create_Log(
                    userId=random.randint(1,10),
                    LogType=Log.LogTypeChoices.LINK.name,
                    LogOption=Log.LogOptionChoices.CREATE.name,
                    LogResult=Log.LogResultChoices.SUCCESS.name,
                    LogOptionDetail=f"创建Link数据成功, linkid: {link.LinkId}",
                )
            except Exception as e:
                # 记录日志失败不应该影响主流程
                log_error(e, context={"action": "记录创建Link日志", "link_id": link.LinkId})
        except Exception as e:
            log_error(e, context={"action": "创建Link", "data": data})
            raise errors.ParamsError(f"创建Link失败: {str(e)}")

    return render_json()

# 查询link数据
@log_api_call
@query_log
@exception_handler
def get_link(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        log_error(e, context={"action": "解析link查询请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
        raise errors.ParamsError("无效的JSON数据")
    
    # 获取当前登录用户ID
    user_id = request.session.get('user_id')
    print(user_id)
    if not user_id:
        log_error("未登录用户尝试获取链接数据", context={"request": str(request)})
        raise errors.AuthError("请先登录")
    
    try:
        # 获取当前用户
        current_user = User.objects.get(userId=user_id)
        
        # 获取当前用户的id
        userIDs = [current_user.userId]
        
        # 获取当前用户的所有下层用户
        if hasattr(current_user, 'managed_users'):
            managed_users = current_user.managed_users.all()
            # 将所有下层用户的邮箱加入到列表中
            for user in managed_users:
                userIDs.append(user.userId)
        
        # 创建过滤条件：链接的用户邮箱在当前用户及其下层用户的邮箱列表中
        filters = Q(user_id__in=userIDs)
        
        # 从数据库获取链接数据
        links = Link.objects.filter(filters).order_by("-LinkId")
        
        # 如果没有符合条件的记录，返回空列表
        if not links.exists():
            return render_json(data=[])
            
        # 将其转为字典列表
        links_list = [link.to_dict() for link in links]
        
        return render_json(data=links_list)
    except User.DoesNotExist:
        log_error(f"用户不存在: {user_id}", context={"user_id": user_id})
        raise errors.AuthError("用户不存在")
    except Exception as e:
        log_error(e, context={"action": "获取链接数据", "user_id": user_id})
        raise errors.SystemError("获取链接数据失败")


# def get_link(request):
#     try:
#         data = json.loads(request.body)
#     except Exception as e:
#         log_error(e, context={"action": "解析link查询请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
#         raise errors.ParamsError("无效的JSON数据")
    
#     # 通过用户邮箱获取对应的 Link 对象
#     user_email = 'mynar8879@gmail.com'
    
#     # 创建过滤条件
#     filters = Q()
    
#     try:
#         # 从数据库获取链接数据
#         links = Link.objects.filter(filters).order_by("-LinkId")
        
#         # 如果没有符合条件的记录，返回空列表
#         if not links.exists():
#             return render_json(data=[])
            
#         # 将其转为字典列表
#         links_list = [link.to_dict() for link in links]
        
#         return render_json(data=links_list)
#     except Exception as e:
#         log_error(e, context={"action": "获取链接数据", "user_email": user_email})
#         raise errors.SystemError("获取链接数据失败")

# 修改link 更新时间数据
@log_api_call
@update_log
@exception_handler
def update_link_interval(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        log_error(e, context={"action": "解析link更新时间间隔请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
        raise errors.ParamsError("无效的JSON数据")
    
    required_fields = [
        "LinkId", "InterVal"
    ]

    missing_fields = [field for field in required_fields if field not in data]
    if missing_fields:
        log_error(f"缺少必填字段: {missing_fields}", context={"data": data})
        raise errors.ParamsError(f"缺少必填字段: {', '.join(missing_fields)}")
    
    # 验证InterVal是否为合法数字
    try:
        interval = int(data["InterVal"])
        if interval < 0:
            log_error("时间间隔不能为负数", context={"InterVal": interval})
            raise errors.ParamsError("时间间隔不能为负数")
    except ValueError:
        log_error("时间间隔必须是数字", context={"InterVal": data["InterVal"]})
        raise errors.ParamsError("时间间隔必须是数字")
    
    try:
        # 检查Link是否存在
        try:
            link = Link.objects.get(LinkId=data["LinkId"])
        except Link.DoesNotExist:
            log_error(f"Link不存在: {data['LinkId']}", context={"data": data})
            raise errors.ParamsError(f"Link不存在: {data['LinkId']}")
        
        # 记录旧值，用于日志
        old_interval = link.InterVal
        
        # 更新字段
        link.InterVal = interval
        link.save()
        
        # 记录操作日志
        try:
            Log.create_Log(
                userId=random.randint(1,10),
                LogType=Log.LogTypeChoices.LINK.name,
                LogOption=Log.LogOptionChoices.UPDATE.name,
                LogResult=Log.LogResultChoices.SUCCESS.name,
                LogOptionDetail=f"""更新Link数据成功，修改内容如下：
                LinkId: {data["LinkId"]}
                InterVal: {old_interval} -> {interval}
                """
            )
        except Exception as log_error_e:
            # 记录日志失败不影响主流程
            log_error(log_error_e, context={"action": "记录InterVal更新日志", "link_id": data["LinkId"]})
    except errors.ParamsError:
        # 这是已经记录过的错误，直接继续抛出
        raise
    except Exception as e:
        log_error(e, context={"action": "更新Link时间间隔", "data": data})
        raise errors.ParamsError(f"更新Link时间间隔失败: {str(e)}")
    
    return render_json()

# 更改link Swith数据
@log_api_call
@update_log
@exception_handler
def update_link_switch(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        log_error(e, context={"action": "解析link开关状态请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
        raise errors.ParamsError("无效的JSON数据")
    
    # 记录接收到的数据，便于调试
    log_error(f"接收到的数据: {data}", context={"action": "update_link_switch"})
    
    # 先检查数据是否为空
    if not data:
        log_error("请求数据为空", context={"data": data})
        raise errors.ParamsError("请求数据为空")
    
    # 检查字段 - 兼容多种可能的字段名
    link_id = None
    switch_value = None
    
    # 尝试获取ID (支持多种可能的字段名)
    for id_field in ["id", "LinkId", "link_id", "linkId"]:
        if id_field in data:
            link_id = data[id_field]
            break
    
    # 尝试获取开关值 (支持多种可能的字段名)
    for switch_field in ["Swith", "Switch", "switch", "swith", "status", "enabled", "active"]:
        if switch_field in data:
            switch_value = data[switch_field]
            break
    
    # 验证必填字段
    if link_id is None:
        log_error("缺少链接ID字段", context={"data": data})
        raise errors.ParamsError("缺少链接ID字段，请提供 'id' 或 'LinkId'")
    
    if switch_value is None:
        log_error("缺少开关值字段", context={"data": data})
        raise errors.ParamsError("缺少开关状态字段，请提供 'Swith'")
    
    # 验证Swith是否为布尔值或可转换为布尔值
    if not isinstance(switch_value, (bool, int, str)):
        log_error("开关值类型无效", context={"Swith": switch_value, "type": type(switch_value).__name__})
        raise errors.ParamsError("开关值类型无效")
    
    try:
        # 将switch_value转为布尔值
        if isinstance(switch_value, str):
            if switch_value.lower() in ('true', 'yes', '1', 'on'):
                switch_value = True
            elif switch_value.lower() in ('false', 'no', '0', 'off'):
                switch_value = False
            else:
                log_error("无法将字符串转换为布尔值", context={"Swith": switch_value})
                raise errors.ParamsError("无法将字符串转换为布尔值")
        elif isinstance(switch_value, int):
            switch_value = bool(switch_value)
    except Exception as e:
        log_error(e, context={"action": "转换开关值", "Swith": switch_value})
        raise errors.ParamsError(f"无法处理开关值: {str(e)}")
    
    try:
        # 检查Link是否存在
        try:
            link = Link.objects.get(LinkId=link_id)
        except Link.DoesNotExist:
            log_error(f"Link不存在: {link_id}", context={"data": data})
            raise errors.ParamsError(f"Link不存在: {link_id}")
        
        # 记录旧值，用于日志
        old_switch = link.Swith
        mess = "开启" if switch_value else "关闭"
        
        # 更新字段
        link.Swith = switch_value
        link.save()
        
        # 根据开关状态处理任务
        try:
            if switch_value:
                # 启动任务
                print(f"------------{id(scheduler())}------------")
                log_error("启动scheduler", context={"action": "记录Swith更新日志", "link_id": link.LinkId, "Interval": link.LinkId, "interval": link.InterVal})
                scheduler().start_task(link.LinkId, link.InterVal)
            else:
                # 停止任务
                scheduler().stop_task(link.LinkId)
        except Exception as task_e:
            log_error(task_e, context={"action": f"处理任务调度 ({mess})", "link_id": link.LinkId})
            # 任务处理失败不影响开关状态更新
        
        # 记录操作日志
        try:
            Log.create_Log(
                userId=random.randint(1,10),
                LogType=Log.LogTypeChoices.LINK.name,
                LogOption=Log.LogOptionChoices.UPDATE.name,
                LogResult=Log.LogResultChoices.SUCCESS.name,
                LogOptionDetail=f"""更新Link数据成功，修改内容如下：
                LinkId: {link_id}
                Swith: {mess}
                """
            )
        except Exception as log_error_e:
            # 记录日志失败不影响主流程
            log_error(log_error_e, context={"action": "记录Swith更新日志", "link_id": link_id})
    except errors.ParamsError:
        # 这是已经记录过的错误，直接继续抛出
        raise
    except Exception as e:
        log_error(e, context={"action": "更新Link开关状态", "data": data})
        raise errors.ParamsError(f"更新Link开关状态失败: {str(e)}")
    
    return render_json()

# 删除link数据
@log_api_call
@delete_log
@exception_handler
def delete_link(request):
    try:
        data = json.loads(request.body)
    except Exception as e:
        log_error(e, context={"action": "解析link删除请求参数", "raw_body": request.body.decode('utf-8', errors='replace')})
        raise errors.ParamsError("无效的JSON数据")
    
    # 记录接收到的数据，便于调试
    log_error(f"接收到的数据: {data}", context={"action": "delete_link"})
    
    # 先检查数据是否为空
    if not data:
        log_error("请求数据为空", context={"data": data})
        raise errors.ParamsError("请求数据为空")
    
    # 尝试获取ID (支持多种可能的字段名)
    link_id = None
    for id_field in ["id", "LinkId", "link_id", "linkId"]:
        if id_field in data:
            link_id = data[id_field]
            break
    
    # 验证必填字段
    if link_id is None:
        log_error("缺少链接ID字段", context={"data": data})
        raise errors.ParamsError("缺少链接ID字段，请提供 'id' 或 'LinkId'")
    
    try:
        # 检查Link是否存在
        try:
            link = Link.objects.get(LinkId=link_id)
        except Link.DoesNotExist:
            log_error(f"Link不存在: {link_id}", context={"data": data})
            raise errors.ParamsError(f"Link不存在: {link_id}")
        
        linkid = link.LinkId
        
        # 删除链接前停止任务
        try:
            scheduler().stop_task(link.LinkId)
        except Exception as task_e:
            log_error(task_e, context={"action": "停止任务", "link_id": link.LinkId})
            # 任务停止失败不影响删除操作
        
        # 删除链接
        link.delete()
        
        # 记录操作日志
        try:
            Log.create_Log(
                userId=random.randint(1,10),
                LogType=Log.LogTypeChoices.LINK.name,
                LogOption=Log.LogOptionChoices.DELETE.name,
                LogResult=Log.LogResultChoices.SUCCESS.name,
                LogOptionDetail=f"删除Link数据成功，LinkId: {linkid}",
            )
        except Exception as log_error_e:
            # 记录日志失败不影响主流程
            log_error(log_error_e, context={"action": "记录删除Link日志", "link_id": linkid})
    except errors.ParamsError:
        # 这是已经记录过的错误，直接继续抛出
        raise
    except Exception as e:
        log_error(e, context={"action": "删除Link", "link_id": link_id})
        raise errors.ParamsError(f"删除Link失败: {str(e)}")
    
    return render_json()


@log_api_call
@exception_handler
def upload_excel(request):
    try:
        excel_file = request.FILES.get('file')
        if excel_file is None:
            log_error("未提供Excel文件", context={"action": "上传Excel文件"})
            return render_json(message="请上传Excel文件", code=400)
        
        try:
            # 使用 openpyxl 读取Excel文件
            workbook = openpyxl.load_workbook(excel_file)
            
            # 处理你的工作簿...
            # 例如，获取第一个工作表
            worksheet = workbook.worksheets[0]
            
            # 获取表头（第一行作为 key）
            keys = [cell.value for cell in worksheet[1]]
            if not keys or len(keys) < 1:
                log_error("Excel文件格式无效：没有找到表头", context={"action": "解析Excel表头"})
                return render_json(message="Excel文件格式无效：没有找到表头", code=400)

            # 解析数据（第二行开始每一行作为字典的一部分）
            data = []
            for row in worksheet.iter_rows(min_row=2, values_only=True):
                row_data = {keys[i]: row[i] for i in range(len(keys)) if i < len(row)}
                data.append(row_data)

            if not data:
                log_error("Excel文件没有数据行", context={"action": "解析Excel数据"})
                return render_json(message="Excel文件没有数据行", code=400)
            
            # 处理数据...
            success_data = []
            fail_data = []
            links = []
            for row in data:
                try:
                    params_res = check_link_params(row)
                    if params_res == 1:
                        success_data.append(row.get("OfferLink"))
                        links.append(Link(
                            MCCName = row.get("MCCName", ""),
                            UserEmail = row.get("UserEmail", "admin@qq.com"),
                            MCCAccount = row.get("MCCAccount", ""),
                            GoogleAccount = row.get("GoogleAccount", ""),
                            CampaignName = row.get("CampaignName", ""),
                            finalUrl = row.get("finalUrl", ""),
                            OfferLink = row.get("OfferLink"),
                            redirect = row.get("redirect"),
                            TargetNation = row.get("TargetNation"),
                            URLldentifiers = row.get("URLldentifiers"),
                            InterVal = row.get("InterVal", 0),
                            Swith = row.get("Swith", False),
                        ))
                    elif params_res == -1:
                        fail_data.append((row.get("OfferLink", "未知链接"), "参数不全"))
                    elif params_res == -2:
                        fail_data.append((row.get("OfferLink", "未知链接"), "参数校验失败"))
                    elif params_res == -3:
                        fail_data.append((row.get("OfferLink", "未知链接"), "OfferLink已经存在！"))
                except Exception as row_e:
                    log_error(row_e, context={"action": "处理Excel数据行", "row": row})
                    fail_data.append((row.get("OfferLink", "未知链接"), f"处理异常: {str(row_e)[:100]}"))
            
            # 批量创建链接
            try:
                Link.objects.bulk_create(links)
            except Exception as bulk_e:
                log_error(bulk_e, context={"action": "批量创建链接", "links_count": len(links)})
                raise errors.ParamsError(f"批量创建链接失败: {str(bulk_e)}")
            
            # 日志添加
            success_mess = "\n".join(success_data) if success_data else "无"
            fail_mess = "\n".join([f"{link[0]}: {link[1]}" for link in fail_data]) if fail_data else "无"

            try:
                Log.create_Log(
                    userId=random.randint(1,10),
                    LogType=Log.LogTypeChoices.LINK.name,
                    LogOption=Log.LogOptionChoices.ADD.name,
                    LogResult=Log.LogResultChoices.SUCCESS.name,
                    LogOptionDetail=f"""Excel文件处理成功
                    成功添加OfferLink: {success_mess}

                    处理失败OfferLink: {fail_mess}"""
                )
            except Exception as log_e:
                # 记录日志失败不影响主流程
                log_error(log_e, context={"action": "记录Excel处理日志"})
            
            return render_json(
                message="Excel文件处理完成", 
                data={
                    "success_count": len(success_data),
                    "fail_count": len(fail_data),
                    "failures": fail_data if fail_data else None
                }
            )
        except openpyxl.utils.exceptions.InvalidFileException:
            log_error("无效的Excel文件格式", context={"action": "读取Excel文件"})
            return render_json(message="无效的Excel文件格式", code=400)
        except Exception as e:
            log_error(e, context={"action": "处理Excel文件", "filename": getattr(excel_file, 'name', 'unknown')})
            raise errors.ParamsError(f"处理Excel文件失败: {str(e)}")
    except Exception as e:
        log_error(e, context={"action": "上传Excel文件"})
        raise errors.ParamsError(f"上传Excel文件失败: {str(e)}")


@log_api_call
def run_all_links(request):
    print("run_all_links")
    try:
        RUN_S = []
        RUN_F = []
        LogStartTime = get_now_time()
        links = Link.objects.filter(Swith=True)
        
        # 获取当前时间戳
        current_time = time.time()
        
        for link in links:
            try:
                if link.fail_num <= 5:
                    print(f"=========={id(scheduler())}==========")
                    print(link.LinkId, link.fail_num, scheduler().is_task_running(link.LinkId))
                    
                    # 获取任务信息
                    task_info = scheduler()._get_task_info(link.LinkId)
                    
                    # 检查是否需要重启任务
                    need_restart = False
                    if task_info:
                        last_run = task_info.get('last_run')
                        next_run = task_info.get('next_run')
                        if not last_run and (current_time - next_run) > 300:  # 300秒 = 5分钟
                            need_restart = True
                            print(f"任务 {link.LinkId} 最后执行时间超过5分钟，需要重启")
                    
                    # 如果任务未运行或需要重启，则启动任务
                    if not scheduler().is_task_running(link.LinkId) or need_restart:
                        if need_restart:
                            # 先停止旧任务
                            scheduler().stop_task(link.LinkId)
                        # 启动新任务
                        scheduler().start_task(link.LinkId, link.InterVal)
                        RUN_S.append(link.LinkId)
                else:
                    link.Swith = False
                    link.save()
                    if scheduler().is_task_running(link.LinkId):
                        scheduler().stop_task(link.LinkId)
            except Exception as e:
                RUN_F.append((link.LinkId, e))
                print(f"处理任务 {link.LinkId} 时发生错误: {str(e)}")
        
        s_RUN_S = str(RUN_S)
        s_RUN_F = str(RUN_F)
        Log.create_Log(
            userId=random.randint(1,10),
            LogType=Log.LogTypeChoices.LINK.name,
            LogOption=Log.LogOptionChoices.RUNNING.name,
            LogResult=Log.LogResultChoices.SUCCESS.name,
            LogOptionDetail=f"""初始化启动Link数据{id(scheduler())} 
            成功启动LinkId: {s_RUN_S}  
            启动失败LinkId: {s_RUN_F}""",
            LogStartTime=LogStartTime,
        )
        return render_json(message="Link data initialized successfully.", data={"LogOptionDetail": f"""初始化启动Link数据{id(scheduler())} 
            成功启动LinkId: {s_RUN_S}  
            启动失败LinkId: {s_RUN_F}"""})
    except Exception as e:
        print("error: ", e)
        raise errors.ParamsError


@shared_task
def hourly_task():
    print("hourly_task begin")
    run_all_links()
    print("hourly_task end")

# 通过id获取link,并且获取最中的url
@query_log
def run_link_by_id(link_id):
    try:
        link = Link.objects.filter(LinkId=link_id)
        # 将其转为字典列表
        linkData = link.to_dict()

        try:
            final_url, log_des = my_get_link(linkData.get("OfferLink"), linkData.get("TargetNation"), linkData.get("redirect"), linkData.get("URLldentifiers"), referrer=linkData.get("referrer"))
            link.update(finalUrl=final_url)
            Log.create_Log(
                userId=1,
                LogType=Log.LogTypeChoices.LINK.name,
                LogOption=Log.LogOptionChoices.RUNNING.name,
                LogResult=Log.LogResultChoices.SUCCESS.name,
                LogOptionDetail=f"""
                运行LinkId: {link_id}
                详细过程: {log_des}""",
            )
        except Exception as e:
            pass #print("e: ", e)
    except Exception as e:
        pass #print("e: ", e)


# def email_to_allLinks(request):
#     # TODO: 获取所有link
#     # TODO: 发送邮件
#     pass #print(request.GET.get('email'))
#     links = Link.objects.filter(UserEmail=request.GET.get('email'))
#     links_data = [
#         link.to_dict() for link in links
#     ]
#     return render_json(data=links_data)

def email_to_allLinks(request):
    email = request.GET.get('email')
    if not email:
        return render_json(data=[], message="请提供邮箱地址", code=400)
    
    try:
        # 先查找该邮箱对应的用户
        # user = User.objects.filter(userEmail=email).first()
        # if not user:
        #     return render_json(data=[], message="未找到该邮箱对应的用户", code=404)
        
        # # 获取该用户的邮箱和所有下级用户的邮箱
        # user_emails = [user.userEmail]
        
        # # 获取下级用户邮箱
        # if hasattr(user, 'managed_users'):
        #     managed_users = user.managed_users.all()
        #     for managed_user in managed_users:
        #         user_emails.append(managed_user.userEmail)
        
        # 查询所有相关邮箱的链接
        links = Link.objects.filter(UserEmail=email)
        links_data = [link.to_dict() for link in links]
        
        return render_json(data=links_data)
    except Exception as e:
        log_error(e, context={"action": "获取所有链接", "email": email})
        return render_json(data=[], message=f"获取链接失败: {str(e)}", code=500)